﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using CH.Easy.DbProvider.Entity;
using System.Linq.Expressions;
using CH.Easy.DbProvider.Common;
using System.Reflection;
using CH.Easy.DbProvider.ExpressionExtend;

namespace CH.Easy.DbProvider.Core
{









    public class ExpressionSolution
    {

        private ExpressionTSQLTranslator translator;
        public ExpressionSolution(DbProviderType dbProviderType)
        {


            this.translator = (ExpressionTSQLTranslator)Assembly.GetExecutingAssembly().CreateInstance("CH.Easy.DbProvider.Provider." + dbProviderType.ToString() + "ExpressionTSQLTranslator"); ;

        }

        public SolutionResult Work(Expression expression)
        {
            SolutionResult solutionResult = new SolutionResult();
            ExpressionAnalyse analyse = ExpressionAnalyseFactory.Create(expression);
            solutionResult.Expression = analyse.Work();
            solutionResult.ResultExpression = analyse.GetResultExpression();
            solutionResult.ExecuteType = analyse.GetExecuteType();


            solutionResult.CmdText = translator.Translator(solutionResult.Expression);
            solutionResult.Parameter = translator.GetParameter();
            

            if (solutionResult.IsPage)
            {
                solutionResult.CountSolutionResult = this.GetCountExpressionSolutionResult(solutionResult.Expression);
            }
            
            if (solutionResult.ResultExpression != null)
            {
                solutionResult.ResultType = DbProviderHelper.GetElementType(solutionResult.ResultExpression.ReturnType);
            }
            else
            {
                solutionResult.ResultType = typeof(object);
            }
            return solutionResult;
        }

        public SolutionResult GetCountExpressionSolutionResult(Expression expression)
        {
            SolutionResult solutionResult = new SolutionResult();
            SelectExpression e = expression as SelectExpression;
            SelectExpression sc = new SelectExpression(e.Expression);
            sc.Where = e.Where;
            sc.From = e.From;
            sc.Column = new ColumnExpression(Expression.Call(typeof(MethodExtend).GetMethod("Count"), Expression.Constant(1)));
            sc.Take = new TakeExpression(null);
            sc.Skip = new SkipExpression(null);
            sc.Order = new OrderExpression();
            sc.Group = new GroupExpression(null);
            sc.InnerJoin = new InnerJoinExpression(null);
            solutionResult.Expression = sc;
            solutionResult.CmdText = translator.Translator(solutionResult.Expression);
            solutionResult.Parameter = translator.GetParameter();
            solutionResult.ResultExpression = null;
            solutionResult.ExecuteType = ExecuteType.ExecuteScalar;
            solutionResult.ResultType = typeof(object);
            return solutionResult;
        }

    }


}
